package cn.com.srit.service.impl;

import cn.com.srit.entity.MenuEntity;
import cn.com.srit.repository.MenuRepository;
import cn.com.srit.service.MenuService;
import cn.com.srit.util.BeanUtils;
import cn.com.srit.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

@Service
public class MenuServiceImpl implements MenuService {
    @Autowired
    private MenuRepository menuRepository;

    @Override
    public List<MenuEntity> findAll(MenuEntity template) {
        return menuRepository.findAll(new Specification<MenuEntity>() {
            @Override
            public Predicate toPredicate(Root<MenuEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                return getCriteriaPredicate(root, criteriaQuery, criteriaBuilder, template);
            }
        });
    }

    @Override
    @Transactional
    public String save(MenuEntity menu) {
        String result;
        try {
            if (!StringUtils.hasText(menu.getId())) {
                menu.setCreateTime(DateUtils.getCurrentTime());
                menu.setState(true);
            } else {
                BeanUtils.copyNullProperties(menuRepository.findOne(menu.getId()), menu);
                menu.setUpdateTime(DateUtils.getCurrentTime());
            }
            menuRepository.saveAndFlush(menu);
            result = "success";
        } catch (Exception e) {
            result = "error";
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }

    @Override
    @Transactional
    public String delete(String id) {
        String result;
        try {
            menuRepository.delete(id);
            result = "success";
        } catch (Exception e) {
            result = "error";
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }

    private Predicate getCriteriaPredicate(Root<MenuEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder, MenuEntity template) {
        List<Predicate> predicateList = new ArrayList<>();
        if (StringUtils.hasText(template.getPid())) {
            predicateList.add(criteriaBuilder.equal(root.get("serviceId").as(String.class), template.getPid()));
        }
        return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
    }
}